/**
 * 
 */
package com.cn.practice.clone;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * 克隆模式
 * @author zhangyang
 *
 */
public class ClonePrictice {
public static void main(String[] args) throws CloneNotSupportedException {
	Person person = new Person("张三",15,"男",new Cat("cat"));
	Person clone = (Person)person.clone();
	System.out.println(person.clone());
	System.out.println(person==clone);
	System.out.println(person.cat==clone.cat);
	Person deepClone = (Person)person.deepClone();
	System.out.println(person.cat==deepClone.cat);
}
}

class Person implements Cloneable,Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	String name;
	int age;
	String sex;
	Cat cat;

	public Person(String name, int age, String sex, Cat cat) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.cat = cat;
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", sex=" + sex + ", cat=" + cat + "]";
	}

	/**
	 * 深度克隆实现 序列化反序列化实现或者修改clone方法逻辑实现
	 * 修改clone方法逻辑实现如果需要克隆的东西多很麻烦
	 */
	public Object deepClone() {
		ByteArrayOutputStream bos;
		ObjectOutputStream oos;
		ByteArrayInputStream bis;
		ObjectInputStream ois;
		Object object=null;
		try {
			//序列化输出出去转换为流
			bos=new ByteArrayOutputStream();
			oos=new ObjectOutputStream(bos);
			oos.writeObject(this);
			//输出流转输入流反序列化
			bis=new ByteArrayInputStream(bos.toByteArray());
			ois=new ObjectInputStream(bis);
			object= ois.readObject();
		} catch (Exception e) {
			// TODO: handle exception
		}
		return object;
	}
}
class Cat implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	String name;

	public Cat(String name) {
		super();
		this.name = name;
	}

	@Override
	public String toString() {
		return "Cat [name=" + name + "]";
	}
	
}